package com.binc.testspring.common.config;

import com.binc.testspring.common.exceptions.BaseRuntimeException;
import com.binc.testspring.common.exceptions.BusinessRtException;
import com.binc.testspring.common.pojo.ResResult;
import com.binc.testspring.dto.RestExStatus;
import com.binc.testspring.dto.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Primary;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.xml.bind.ValidationException;
import java.net.BindException;

/**
 * 全局异常处理
 *  这个全局异常处理只能处理从controller抛出的异常，   service抛给了controller，然后controller在跑出来的也行；
 *
 *  异步方法抛出的好像有点问题
 */
@ControllerAdvice //这个很重要
@Primary
public class ExceptionWebAdvice extends ExceptionControllerAdvice {
    private static final Logger log = LoggerFactory.getLogger(ExceptionWebAdvice.class);

    public ExceptionWebAdvice() {
    }



    @Override
    @ExceptionHandler({MissingServletRequestParameterException.class}) //表示要处理的异常类型
    @ResponseBody
    @ResponseStatus(HttpStatus.OK)
    public Result handle(MissingServletRequestParameterException e) {
        log.error(e.getMessage(), e);
        return Result.of(RestExStatus.MISSING_PARAMETERS);
    }

    @Override
    @ExceptionHandler({HttpMessageNotReadableException.class})
    @ResponseBody
    @ResponseStatus(HttpStatus.OK)
    public Result handle(HttpMessageNotReadableException e) {
        log.error(e.getMessage(), e);
        return Result.of(RestExStatus.PARSING_PARAMETERS);
    }

    @Override
    @ExceptionHandler({IllegalArgumentException.class})
    @ResponseBody
    @ResponseStatus(HttpStatus.OK)
    public Result handle(IllegalArgumentException e) {
        log.error(e.getMessage(), e);
        return Result.of(RestExStatus.IRREGULAR_PARAMETERS);
    }

    @ExceptionHandler({BindException.class})
    @ResponseBody
    @ResponseStatus(HttpStatus.OK)
    public Result handle(BindException e) {
        log.error(e.getMessage(), e);
        return Result.of(RestExStatus.BIND_PARAMETERS);
    }



    @Override
    @ExceptionHandler({ValidationException.class})
    @ResponseBody
    @ResponseStatus(HttpStatus.OK)
    public Result handle(ValidationException exception) {
        log.error(exception.getMessage(), exception);
        return Result.of(RestExStatus.VALIDATION_PARAMETERS);
    }

    @Override
    @ExceptionHandler({NoHandlerFoundException.class})
    @ResponseBody
    @ResponseStatus(HttpStatus.OK)
    public Result handle(NoHandlerFoundException e) {
        log.error(e.getMessage(), e);
        return Result.of(RestExStatus.NOT_FOUNT);
    }

    @Override
    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    @ResponseBody
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    public Result handle(HttpRequestMethodNotSupportedException e) {
        log.error(e.getMessage(), e);
        return Result.of(RestExStatus.UN_SUPPORT_METHOD);
    }

    @Override
    @ExceptionHandler({HttpMediaTypeNotSupportedException.class})
    @ResponseBody
    @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
    public Result handle(HttpMediaTypeNotSupportedException e) {
        log.error(e.getMessage(), e);
        return Result.of(RestExStatus.UN_SUPPORT_MEDIA);
    }

    // @Override
    // @ExceptionHandler({MethodArgumentNotValidException.class})
    // @ResponseStatus(HttpStatus.OK)
    // @ResponseBody
    // public RestResult<Object> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
    //     log.warn("handleMethodArgumentNotValidException( MethodArgumentNotValidException e ) ", e);
    //     RestResult<Object> restResult = new RestResult();
    //     StringBuilder msg = new StringBuilder();
    //     e.getBindingResult().getAllErrors().forEach(item->msg.append(item.getDefaultMessage()).append(";"));
    //     restResult.setMsg(msg.toString());
    //     restResult.setCode("500");
    //     restResult.setSucceed(false);
    //     return restResult;
    // }

    // @ExceptionHandler({DataAccessException.class})
    // @ResponseBody
    // @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    // public RestResult dataAccessException(DataAccessException e) {
    //     log.error("dataAccessException(DataAccessException e)->", e);
    //     RestResult result = new RestResult();
    //     result.setCode("500");
    //     result.setSucceed(false);
    //     result.setMsg("系统错误 ！遗漏的数据操作异常");
    //     return result;
    // }

    // @Override
    // @ExceptionHandler({BaseException.class})
    // @ResponseStatus(HttpStatus.OK)
    // @ResponseBody
    // public RestResult handleBusinessException(BaseException e) {
    //     log.error("Base Exception handler ->", e);
    //     RestResult restResult = new RestResult();
    //     restResult.setCode(e.getErrorCode());
    //     restResult.setMsg(e.getMessage());
    //     restResult.setSucceed(false);
    //     return restResult;
    // }

    // @Override
    @ExceptionHandler({BaseRuntimeException.class})
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public ResResult handleBaseRuntimeException(BaseRuntimeException e) {
        if (e instanceof BusinessRtException){
            log.warn("handleBaseRuntimeException->", e);
        }else {
            log.error("handleBaseRuntimeException->", e);
        }
        ResResult restResult = new ResResult();
        restResult.setCode(e.getErrorCode());
        restResult.setMsg(e.getMessage());
        restResult.setSucceed(false);
        return restResult;
    }

    // @Override
    @ExceptionHandler({Exception.class})
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public ResResult<Object> handleException(Exception e) {
        log.error("unknown Exception handler ->", e);
        ResResult restResult = new ResResult();
        restResult.setSucceed(false);
        restResult.setMsg("系统错误！");
        restResult.setCode("500");
        return restResult;
    }


}
